<?php
/**
 *	KLF Framework
 *
 *	Written by Kristian Oye <kristianoye@gmail.com> on Dec 10, 2011
 *	Copyright (C) 2010-2011
 */
namespace KLF\System\Data
{
	use KLF\System\KObject;

	/**
	 *  Class KPreferenceMap
	 *
	 *  Container for a 
	 *
	 *  @package package
	 *  @access access
	 *  @author Kristian Oye <kristianoye@gmail.com>
	 *  @since version
	 *
	 *  @method KPreferenceMap NewInstance
	 */
	class KPreferenceMap extends KObject
	{
		/**
		 * A description of what the list is (e.g. language, encoding, etc).
		 * 
		 * @var string $_propPreferenceType
		 */
		protected $_propPreferenceType;
		
		/**
		 * Contains a mapping of weighted preferences where 1.0 is the most preferred and other
		 * acceptable types follow.
		 * 
		 * @var array $_rpropPreferenceList
		 */
		protected $_rpropPreferenceList;
		
		public function __construct($prefName, $strValue = '')
		{
			parent::__construct();
			
			$this->_propPreferenceType = $prefName;
			$types = preg_split('/\s*,\s*/', (isset($strValue) ? $strValue : ''));
			$map = array();
			foreach ($types as $t)
			{
				$data = array();
				if (!preg_match('/(?<type>[^;]+)\s*;\s*q=(?<qvalue>[\d]{0,1}\.[\d]{0,1})/', $t, $data))
				{
					$data['type'] = $t;
					$data['qvalue'] = 1.0;
				}
				$map[$data['type']] = $data['qvalue'];
			}
			$this->_rpropPreferenceList = $map;
		}
		
		/**
		 * Given a list of possible choices as arguments, which would be the 'preferred' choice 
		 * according to the weighted list contained within.
		 * 
		 * Example:<br/>
		 * <pre>
		 * $preference = $obj->PreferredChoice('text/plain', 'text/html', 'application/xml');
		 * </pre>
		 */
		public function PreferredChoice()
		{
			$matches = array();
			
			foreach(func_get_args() as $arg)
			{
				foreach($this->_rpropPreferenceList as $type => $weight)
				{
					//  Does it match?
					if ($type === $arg){
						$matches[$arg] = $weight;
					}
					//  Is it a wildcard?
					else if (strpos($type, '*') > -1) {
						$pattern = '/^' . addcslashes(str_replace('*', '.*', $type), '/') . '$/';
						if (preg_match($pattern, $arg))
						{
							if (!isset($matches[$arg]))
							{
								$matches[$arg] = $weight;
							}
							elseif ($matches[$arg] < $weight)
							{
								$matches[$arg] = $weight;
							}
						}	
					}
				}
			}
			if (count($matches) > 0) 
			{
				$list = array_keys($matches);
				usort($list, function ($a, $b) use ($matches)
				{
					return ($matches[$a] < $matches[$b]) ? 1 : -1;
				});
				return $list[0];
			}
			return false;
		}
	}
}